package com.xujie.sportsmeeting.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xujie.sportsmeeting.dto.AthleteQueryDTO;
import com.xujie.sportsmeeting.entity.Athlete;
import com.xujie.sportsmeeting.entity.SysUser;
import com.xujie.sportsmeeting.entity.SysUserRole;
import com.xujie.sportsmeeting.mapper.AthleteMapper;
import com.xujie.sportsmeeting.mapper.SysUserRoleMapper;
import com.xujie.sportsmeeting.service.AthleteService;
import com.xujie.sportsmeeting.service.SysUserService;
import org.springframework.security.crypto.password.PasswordEncoder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

/**
 * 运动员服务实现类
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AthleteServiceImpl extends ServiceImpl<AthleteMapper, Athlete> implements AthleteService {

    private final SysUserService sysUserService;
    private final PasswordEncoder passwordEncoder;
    private final SysUserRoleMapper sysUserRoleMapper;

    @Override
    public IPage<Athlete> getAthletePage(IPage<Athlete> page, AthleteQueryDTO queryDTO) {
        LambdaQueryWrapper<Athlete> wrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(queryDTO.getStudentNumber())) {
            wrapper.like(Athlete::getStudentNumber, queryDTO.getStudentNumber());
        }
        
        if (StringUtils.hasText(queryDTO.getRealName())) {
            wrapper.like(Athlete::getRealName, queryDTO.getRealName());
        }
        
        if (StringUtils.hasText(queryDTO.getDepartment())) {
            wrapper.like(Athlete::getDepartment, queryDTO.getDepartment());
        }
        
        if (StringUtils.hasText(queryDTO.getClassName())) {
            wrapper.like(Athlete::getClassName, queryDTO.getClassName());
        }
        
        if (queryDTO.getGender() != null) {
            wrapper.eq(Athlete::getGender, queryDTO.getGender());
        }
        
        if (queryDTO.getStatus() != null) {
            wrapper.eq(Athlete::getStatus, queryDTO.getStatus());
        }
        
        wrapper.orderByDesc(Athlete::getCreateTime);
        
        return this.page(page, wrapper);
    }

    @Override
    @Transactional
    public boolean createAthlete(Athlete athlete) {
        // 检查学号是否已存在
        Athlete existingAthlete = findByStudentNumber(athlete.getStudentNumber());
        if (existingAthlete != null) {
            throw new RuntimeException("学号已存在");
        }
        
        try {
            // 1. 检查用户名是否已存在
            LambdaQueryWrapper<SysUser> userWrapper = new LambdaQueryWrapper<>();
            userWrapper.eq(SysUser::getUsername, athlete.getStudentNumber());
            SysUser existingUser = sysUserService.getOne(userWrapper);
            
            SysUser user;
            if (existingUser != null) {
                // 用户已存在，使用现有用户
                user = existingUser;
                log.info("用户名 {} 已存在，使用现有用户账号: userId={}", athlete.getStudentNumber(), user.getId());
            } else {
                // 创建新用户账号
                user = new SysUser();
                user.setUsername(athlete.getStudentNumber());
                user.setPassword(passwordEncoder.encode("123456")); // 默认密码
                user.setRealName(athlete.getRealName());
                user.setGender(athlete.getGender());
                user.setPhone(athlete.getPhone());
                user.setEmail(athlete.getEmail());
                user.setDepartment(athlete.getDepartment());
                user.setStatus(1); // 启用
                
                boolean userCreated = sysUserService.save(user);
                if (!userCreated) {
                    throw new RuntimeException("创建用户账号失败");
                }
                log.info("成功创建新用户账号: username={}, userId={}", athlete.getStudentNumber(), user.getId());
            }
            
            // 2. 设置运动员的user_id关联
            athlete.setUserId(user.getId());
            
            // 3. 保存运动员信息
            boolean athleteCreated = this.save(athlete);
            if (!athleteCreated) {
                throw new RuntimeException("创建运动员信息失败");
            }
            
            // 4. 为运动员用户分配"运动员"角色 (role_id = 4)
            // 检查是否已分配运动员角色
            LambdaQueryWrapper<SysUserRole> roleWrapper = new LambdaQueryWrapper<>();
            roleWrapper.eq(SysUserRole::getUserId, user.getId())
                      .eq(SysUserRole::getRoleId, 4L);
            SysUserRole existingRole = sysUserRoleMapper.selectOne(roleWrapper);
            
            if (existingRole == null) {
                // 还没有分配运动员角色，进行分配
                SysUserRole userRole = new SysUserRole();
                userRole.setUserId(user.getId());
                userRole.setRoleId(4L); // 运动员角色ID
                
                int roleAssigned = sysUserRoleMapper.insert(userRole);
                if (roleAssigned <= 0) {
                    log.warn("为运动员用户分配角色失败: userId={}", user.getId());
                } else {
                    log.info("成功为运动员用户分配角色: userId={}, roleId=4", user.getId());
                }
            } else {
                log.info("用户 {} 已具有运动员角色，跳过角色分配", user.getId());
            }
            
            log.info("成功创建运动员用户: username={}, athleteId={}, realName={}", 
                    athlete.getStudentNumber(), athlete.getId(), athlete.getRealName());
            return true;
            
        } catch (Exception e) {
            log.error("创建运动员失败: {}", e.getMessage(), e);
            throw new RuntimeException("创建运动员失败: " + e.getMessage());
        }
    }

    @Override
    @Transactional
    public boolean updateAthlete(Athlete athlete) {
        // 检查学号是否已存在（排除当前运动员）
        LambdaQueryWrapper<Athlete> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Athlete::getStudentNumber, athlete.getStudentNumber())
               .ne(Athlete::getId, athlete.getId());
        Athlete existingAthlete = this.getOne(wrapper);
        if (existingAthlete != null) {
            throw new RuntimeException("学号已存在");
        }
        
        return this.updateById(athlete);
    }

    @Override
    public boolean updateAthleteStatus(Long athleteId, Integer status) {
        Athlete athlete = new Athlete();
        athlete.setId(athleteId);
        athlete.setStatus(status);
        return this.updateById(athlete);
    }

    @Override
    public Athlete findByStudentNumber(String studentNumber) {
        LambdaQueryWrapper<Athlete> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Athlete::getStudentNumber, studentNumber);
        return getOne(wrapper);
    }

    @Override
    public Athlete findByUserId(Long userId) {
        LambdaQueryWrapper<Athlete> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Athlete::getUserId, userId);
        return getOne(wrapper);
    }
}
